#ifndef TREE_H
#define TREE_H

#include <string>

using namespace std;

class Node {

	public:
                            Node(void);
				     Node   *getLft(void) { return lft; }
				     Node   *getRht(void) { return rht; }
				     Node   *getAnc(void) { return anc; }
					  int   getIndex(void) { return index; }
                     bool   getIsLeaf(void) { return isLeaf; }
				   string   getName(void) { return name; }
				     bool   getFlag(void) { return flag; }
				   double   getV(void) { return v; }
				     void   setLft(Node *p) { lft = p; }
					 void   setRht(Node *p) { rht = p; }
					 void   setAnc(Node *p) { anc = p; }
					 void   setIndex(int x) { index = x; }
					 void   setIsLeaf(bool x) { isLeaf = x; }
					 void   setName(string s) { name = s; }
					 void   setFlag(bool x) { flag = x; }
					 void   setV(double x) { v = x; }

	private:
				     Node   *lft;
				     Node   *rht;
				     Node   *anc;
				      int   index;
					 bool   isLeaf;
				   string   name;
				     bool   flag;
				   double   v;

};

class Alignment;
class MbRandom;
class Tree {

	public:
                            Tree(Alignment *al, MbRandom *rp, string treeStr);
							~Tree(void);
					  int   getNumTaxa(void) { return numTaxa; }
					  int   getNumNodes(void) { return numNodes; }
				     void   getDownPassSequence(void);
					 Node   *getRoot(void) { return root; }
					 Node   *getDownPassNode(int i) { return downPassSequence[i]; }
					 void   print(void);

	private:
					 void   buildTreeFromNewickString(string treeStr);
					 void   buildRandomTree(void);
					  int   dex(Node *p);
					 void   passDn(Node *p, int *x);
					 void   showNodes(Node *p, int indent);
			    Alignment   *alignmentPtr;
				 MbRandom   *ranPtr;
				     Node   *nodes;
				     Node   *root;
					 Node   **downPassSequence;
					  int   numTaxa;
					  int   numNodes;
					 bool   isRooted;

};

#endif
